#include "../include/head.h"
#include "../include/func.h"

int recv_file_mmap(int socketfd, char *filename, off_t filesize) {
    int ret = -1;

    int fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
    ERROR_CHECK(fd, -1, "open");

    //拉屎先占坑
    ret = ftruncate(fd, filesize);
    ERROR_CHECK(ret, -1, "ftruncate");

    printf("recv start...\n");
    char *p = (char *)mmap(NULL, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    ERROR_CHECK(p, MAP_FAILED, "mmap" );

    ret = recv(socketfd, p, filesize, MSG_WAITALL);
    if (ret == 0) {
        munmap(p, filesize);
        close(fd);
        return -2;
    }
    munmap(p, filesize);
    printf("recv finished!\n");
    close(fd);
    return 0;
}

int get_filesize(char *filename) {
    int ret = access(filename, F_OK);
    if (ret == 0) {
        struct stat st;
        stat(filename, &st);
        return st.st_size;
    }
    return 0;
}

int recv_file_train(int sockfd, char *filename) {
    Train_t train = {0};
    int ret = -1;

    //断点续传
    //在本地寻找文件，有的话则发送文件大小，没有则发送0
    int offset = get_filesize(filename);
    send(sockfd, &offset, sizeof(int), 0);
    printf("offset: %d\n", offset);

    //打开文件并且进行指针偏移
    int fd = open(filename, O_WRONLY | O_CREAT, 0666);
    ERROR_CHECK(fd, -1, "open");
    
    if (offset != 0) {
        lseek(fd, offset, SEEK_SET);
    }
    
    while (1) {
        memset(&train, 0, sizeof(Train_t));

        //先接文件的长度
        recv(sockfd, &train._data_len, sizeof(int), MSG_WAITALL);
        if (train._data_len == 0) {
            printf("transfer finished!\n");
            close(fd);
            return 0;
        }
        ret = recv(sockfd, train._data, train._data_len, MSG_WAITALL);
        if (ret == 0) {
            close(fd);
            return -2;
        }
        //将接收到的文件写入文件
        write(fd, train._data, ret);
    }
    return 0;
}
